package com.nmtg.web_service_to_jdbc.test.service;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import com.nmtg.web_service_to_jdbc.test.common_objects.check_nat_prs_out;
import com.nmtg.web_service_to_jdbc.test.common_objects.check_nat_prs_in;

import com.nmtg.web_service_to_jdbc.test.office_private_user_package;
import com.nmtg.web_service_to_jdbc.test.office_private_user_package_Proxy;
import com.caucho.hessian.io.AbstractDeserializer;
import com.caucho.hessian.io.AbstractHessianInput;
import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.AbstractSerializer;
import com.caucho.hessian.io.AbstractSerializerFactory;
import com.caucho.hessian.io.BeanSerializerFactory;
import com.caucho.hessian.io.Deserializer;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.Serializer;
import com.caucho.hessian.server.HessianServlet;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.apache.commons.beanutils.BeanUtils;


public class office_private_user_package_WS extends HessianServlet implements office_private_user_package{
    private final office_private_user_package_Proxy proxy;
    public office_private_user_package_WS(){
        DataSource dataSource =null;
        try{
            Context initContext = new InitialContext();
            dataSource = (DataSource)initContext.lookup("java:/comp/env/jdbc/data_source");
        }catch(Exception ex){
            System.err.println("create DataSource Exception:"+ex.getMessage());
        }

        this.getSerializerFactory().addFactory(new AbstractSerializerFactory() {
			@Override
			public Serializer getSerializer(Class cl) throws HessianProtocolException {
				System.out.println("Serializer try to load class:"+cl);
				return new AbstractSerializer() {
					@Override
					public void writeObject(Object obj,
							AbstractHessianOutput out) throws IOException {
						if(out instanceof Hessian2Output){
							Hessian2Output output=((Hessian2Output)out);
							String[] properties=getGetters(obj);
							for(String prop:properties){
								try {
									output.writeObject(BeanUtils.getProperty(obj, prop));
								} catch (IllegalAccessException e) {
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									e.printStackTrace();
								} catch (NoSuchMethodException e) {
									e.printStackTrace();
								}
							}
						}
					}
				};
			}
			
			@Override
			public Deserializer getDeserializer(Class cl)
					throws HessianProtocolException {
				System.out.println("Deserializer  try to load class:"+cl);
				return new AbstractDeserializer(){
					@Override
					public Object readObject(AbstractHessianInput in,
							Object[] fields) throws IOException {
						System.out.println("    Method:"+in.getMethod());
						if(in instanceof Hessian2Input){
							Hessian2Input input=(Hessian2Input)in;
							check_nat_prs_in returnValue=new check_nat_prs_in();
							for(Object field:fields){
								Object writeObject=input.readObject();
								if(field instanceof String){
									try {
										BeanUtils.setProperty(returnValue, (String)field, writeObject);
									} catch (IllegalAccessException e) {
										e.printStackTrace();
										System.out.println("AccessException:"+e.getMessage());
									} catch (InvocationTargetException e) {
										e.printStackTrace();
										System.out.println("InvocationTargetException:"+e.getMessage());
									}
								}
							}
							// super.readObject(in, fields);
							return returnValue;
						}else{
							return null;
						}
					}
				};
			}
		});
        this.proxy=new office_private_user_package_Proxy(dataSource);
    }

    private String[] getGetters(Object value){
    	try {
			PropertyDescriptor[] descriptors=Introspector.getBeanInfo(value.getClass()).getPropertyDescriptors();
			ArrayList<String> returnValue=new ArrayList<String>(descriptors.length);
			for(int index=0;index<descriptors.length;index++){
				if(!descriptors[index].getName().equals("class")){
					returnValue.add(descriptors[index].getName());
				}
			}
			return returnValue.toArray(new String[]{});
    	} catch (IntrospectionException e) {
			e.printStackTrace();
			return null;
		}
    }
    
    public check_nat_prs_out check_nat_prs(check_nat_prs_in input){
        return this.proxy.check_nat_prs(input);
    }
    
}